/*---------------------------------------------------------------------------------------------------------*/
/*                                                                                                         */
/* Copyright(c) 2011 Nuvoton Technology Corp. All rights reserved.                                         */
/*                                                                                                         */
/*---------------------------------------------------------------------------------------------------------*/
#ifndef DRVSYS_H
#define DRVSYS_H

#include "NANO1xx.h"


/*---------------------------------------------------------------------------------------------------------*/
/* Macro, type and constant definitions                                                                    */
/*---------------------------------------------------------------------------------------------------------*/
#define	DRVSYS_MAJOR_NUM 1
#define	DRVSYS_MINOR_NUM 00
#define	DRVSYS_BUILD_NUM 1

#define DRVSYS_VERSION_NUM		_SYSINFRA_VERSION(DRVSYS_MAJOR_NUM,DRVSYS_MINOR_NUM,DRVSYS_BUILD_NUM)  

#define E_DRVSYS_ERR_UNLOCK_FAIL    _SYSINFRA_ERRCODE(TRUE, MODULE_ID_DRVSYS, 1)
#define E_DRVSYS_ERR_LOCK_FAIL    	_SYSINFRA_ERRCODE(TRUE, MODULE_ID_DRVSYS, 2)
#define E_DRVSYS_ERR_ARGUMENT      	_SYSINFRA_ERRCODE(TRUE, MODULE_ID_DRVSYS, 3)	
#define E_DRVSYS_ERR_IPSRC      	_SYSINFRA_ERRCODE(TRUE, MODULE_ID_DRVSYS, 4)	
#define E_DRVSYS_ERR_IPDIV      	_SYSINFRA_ERRCODE(TRUE, MODULE_ID_DRVSYS, 5)	
#define E_DRVSYS_ERR_OUT_OF_RANGE   _SYSINFRA_ERRCODE(TRUE, MODULE_ID_DRVSYS, 6)
#define E_DRVSYS_ERR_CLK_UNSTABLE   _SYSINFRA_ERRCODE(TRUE, MODULE_ID_DRVSYS, 7)
#define E_DRVSYS_ERR_PLL_INCLK      _SYSINFRA_ERRCODE(TRUE, MODULE_ID_DRVSYS, 8)
#define E_DRVSYS_ERR_PLL_OUTCLK     _SYSINFRA_ERRCODE(TRUE, MODULE_ID_DRVSYS, 9)
#define E_DRVSYS_ERR_PLL_CLK_SET    _SYSINFRA_ERRCODE(TRUE, MODULE_ID_DRVSYS, 10)
#define E_DRVSYS_ERR_32K_CLK_FAIL   _SYSINFRA_ERRCODE(TRUE, MODULE_ID_DRVSYS, 11)
#define E_DRVSYS_ERR_CLKSWITCH_FAIL	_SYSINFRA_ERRCODE(TRUE, MODULE_ID_DRVSYS, 12)


/*---------------------------------------------------------------------------------------------------------*/
/*  Define parameter checking                                                                              */
/*---------------------------------------------------------------------------------------------------------*/
#define CHECK_BOD_VOLT(Volt)				((Volt == 0) || (Volt == 1) | (Volt == 2))
#define CHECK_BOD_ENABLE(Enable)			((Enable == 0) || (Enable == 1))
#define CHECK_BOD_MODE(Mode)				((Mode == 0) || (Mode == 1))
#define CHECK_IPCLK_SRC(IpClkSrc)			((IpClkSrc == 0) || ((IpClkSrc <= 37) && (IpClkSrc >= 1)))
#define CHECK_HCLK_SOURCE(HclkSel)			((HclkSel == 0) || \
											 (HclkSel == 1)	|| \
											 (HclkSel == 2)	|| \
											 (HclkSel == 3)	|| \
											 (HclkSel == 7))
#define CHECK_IP_CLKSRC(IpClkSrc)           ((IpClkSrc == UART_CLK_SET)     || \
	                                         (IpClkSrc == ADC_CLK_SET)     || \
	                                         (IpClkSrc == TMR0_CLK_SET)    || \
	                                         (IpClkSrc == TMR1_CLK_SET)    || \
	                                         (IpClkSrc == TMR2_CLK_SET)    || \
	                                         (IpClkSrc == TMR3_CLK_SET)    || \
					                         (IpClkSrc == PWM0_CH01_CLK_SET)   || \
	                                         (IpClkSrc == PWM0_CH23_CLK_SET)   || \
	                                         (IpClkSrc == PWM1_CH01_CLK_SET)   || \
	                                         (IpClkSrc == PWM1_CH23_CLK_SET)   || \
	                                         (IpClkSrc == FRQDIV_CLK_SET)  || \
	                                         (IpClkSrc == TK_CLK_SET)    || \
	                                         (IpClkSrc == LCD_CLK_SET)    || \
	                                         (IpClkSrc == I2S_CLK_SET) || \
	                                         (IpClkSrc == SC_CLK_SET))
#define CHECK_IP_CLKDIV(IpClkDiv)            ((IpClkDiv == HCLK_CLK_DIV)  || \
											  (IpClkDiv == USB_CLK_DIV)   || \
											  (IpClkDiv == UART_CLK_DIV)  || \
											  (IpClkDiv == I2S_CLK_DIV)   || \
											  (IpClkDiv == ADC_CLK_DIV)   || \
											  (IpClkDiv == TK_CLK_DIV)    || \
											  (IpClkDiv == SC0_CLK_DIV)   || \
											  (IpClkDiv == SC1_CLK_DIV))										 
#define CHECK_FREQ_DIVIDER(Divider)			(!(Divider > 15))	          
#define CHECK_PLLIN_CLK(PllInClk)	        ((PllInClk == E_SYS_PLLIN_4M)  || \
											 (PllInClk == E_SYS_PLLIN_8M)  || \
											 (PllInClk == E_SYS_PLLIN_12M) || \
											 (PllInClk == E_SYS_PLLIN_15M) || \
											 (PllInClk == E_SYS_PLLIN_24M))
#define CHECK_PLLOUT_CLK(PllOutClk)	        ((PllOutClk == E_SYS_PLLOUT_45M)  || \
											 (PllOutClk == E_SYS_PLLOUT_48M)  || \
											 (PllOutClk == E_SYS_PLLOUT_90M)  || \
											 (PllOutClk == E_SYS_PLLOUT_96M)  || \
											 (PllOutClk == E_SYS_PLLOUT_120M) || \
											 (PllOutClk == E_SYS_PLLOUT_128M))
#define CHECK_CLK_CONFIG(ClkCfg)			 (ClkCfg != NULL)

/*---------------------------------------------------------------------------------------------------------*/
/*  Define IP Clock Source                                                                                 */
/*            Byte3 : Reserved                                                                             */
/*            Byte2 : Clcok Select Register Number                                                         */
/*            Byte1 : Number of shift bits															       */
/*            Byte0 : Clock Selection Mask Bits                                                            */
/*---------------------------------------------------------------------------------------------------------*/
#define UART_CLK_SET		0x00010003
#define ADC_CLK_SET			0x00010203
#define PWM0_CH01_CLK_SET	0x00010403
#define PWM0_CH23_CLK_SET	0x00010603
#define TMR0_CLK_SET		0x00010807
#define TMR1_CLK_SET		0x00010C07
#define TK_CLK_SET			0x00011003
#define LCD_CLK_SET			0x00011201
#define FRQDIV_CLK_SET		0x00020203
#define PWM1_CH01_CLK_SET	0x00020403
#define PWM1_CH23_CLK_SET	0x00020603
#define TMR2_CLK_SET		0x00020807
#define TMR3_CLK_SET		0x00020C07
#define I2S_CLK_SET			0x00021003
#define SC_CLK_SET			0x00021203


/*---------------------------------------------------------------------------------------------------------*/
/*  Define IP Clock Divider                                                                                */
/*            Byte3 : Reserved                                                                             */
/*            Byte2 : Clcok Divide Register Number                                                                            */
/*            Byte1 : Number of shift bits															       */
/*            Byte0 : Clock Divider Mask Bits                                                              */
/*---------------------------------------------------------------------------------------------------------*/
#define HCLK_CLK_DIV	0x0000000F
#define USB_CLK_DIV		0x0000040F
#define UART_CLK_DIV	0x0000080F
#define I2S_CLK_DIV		0x00000C0F
#define ADC_CLK_DIV		0x000010FF
#define TK_CLK_DIV		0x0000180F
#define SC0_CLK_DIV		0x00001C0F
#define SC1_CLK_DIV		0x0001000F


typedef void (*DRVSYS_IRC_CALLBACK)(uint32_t u32IrcStatus);

/*---------------------------------------------------------------------------------------------------------*/
/*  PLL Clock Source Selector						                                                       */
/*---------------------------------------------------------------------------------------------------------*/
typedef enum 
{
	E_SYS_EXTERNAL_HXT = 0,
	E_SYS_INTERNAL_HIRC = 1,	
} E_SYS_PLL_CLKSRC;


/*---------------------------------------------------------------------------------------------------------*/
/*  IP reset						                                                                       */
/*---------------------------------------------------------------------------------------------------------*/
typedef enum 
{
	E_SYS_GPIO_RST  = 1,
	E_SYS_TMR0_RST  = 2,
	E_SYS_TMR1_RST  = 3,
	E_SYS_TMR2_RST  = 4,
	E_SYS_TMR3_RST  = 5,
	E_SYS_I2C0_RST  = 8,
	E_SYS_I2C1_RST  = 9,
	E_SYS_SPI0_RST  = 12,
	E_SYS_SPI1_RST  = 13,
	E_SYS_SPI2_RST  = 14,
	E_SYS_UART0_RST = 16,
	E_SYS_UART1_RST = 17,
	E_SYS_PWM0_RST  = 20,
	E_SYS_PWM1_RST  = 21,
	E_SYS_TK_RST    = 24,
	E_SYS_DAC_RST   = 25,
	E_SYS_LCD_RST   = 26,
	E_SYS_USBD_RST  = 27,
	E_SYS_ADC_RST   = 28,
	E_SYS_I2S_RST   = 29,	
	E_SYS_SC0_RST   = 30,	
	E_SYS_SC1_RST   = 31,	
	E_SYS_PDMA_RST  = 32,
	E_SYS_EBI_RST   = 33
}E_SYS_IP_RST;

/*---------------------------------------------------------------------------------------------------------*/
/*  SYS IP Clcok Selector		     				                                                       */
/*---------------------------------------------------------------------------------------------------------*/

typedef enum 
{
	E_SYS_WDT_CLK   = 0,
	E_SYS_RTC_CLK   = 1,
	E_SYS_TMR0_CLK  = 2,
	E_SYS_TMR1_CLK  = 3,
	E_SYS_TMR2_CLK  = 4,
	E_SYS_TMR3_CLK  = 5,
	E_SYS_FDIV_CLK  = 6,
	E_SYS_I2C0_CLK  = 8,
	E_SYS_I2C1_CLK  = 9,
	E_SYS_SPI0_CLK  = 12,
	E_SYS_SPI1_CLK  = 13,
	E_SYS_SPI2_CLK  = 14,
	E_SYS_UART0_CLK = 16,
	E_SYS_UART1_CLK = 17,
	E_SYS_PWM0_01_CLK = 20,
	E_SYS_PWM0_23_CLK = 21,
	E_SYS_PWM1_01_CLK = 22,
	E_SYS_PWM1_23_CLK = 23,
	E_SYS_TK_CLK    = 24,
	E_SYS_DAC_CLK   = 25,
	E_SYS_LCD_CLK   = 26,
	E_SYS_USBD_CLK  = 27,
	E_SYS_ADC_CLK   = 28,
	E_SYS_I2S_CLK   = 29,
	E_SYS_SC0_CLK   = 30,
	E_SYS_SC1_CLK   = 31,
	E_SYS_GPIO_CLK  = 32,
	E_SYS_PDMA_CLK  = 33,
	E_SYS_ISP_CLK   = 34,
	E_SYS_EBI_CLK   = 35,
	E_SYS_SRAM_CLK   = 36,
	E_SYS_TICK_CLK   = 37
}E_SYS_IP_CLK;


/*---------------------------------------------------------------------------------------------------------*/
/*  TEST Clcok Source Selector		     				                                                       */
/*---------------------------------------------------------------------------------------------------------*/
typedef enum 
{
    E_SYS_TSTCLK_ISP = 0,
	E_SYS_TSTCLK_HIRC = 1,
	E_SYS_TSTCLK_HXT= 2,
	E_SYS_TSTCLK_LXT = 3,
	E_SYS_TSTCLK_LIRC = 4,
	E_SYS_TSTCLK_PLLOUT = 5,
	E_SYS_TSTCLK_PLLIN = 6,
	E_SYS_TSTCLK_TICK = 7,
	E_SYS_TSTCLK_HCLK1 = 8,
	E_SYS_TSTCLK_HCLK2 = 9,
	E_SYS_TSTCLK_PCLK1 = 10,
	E_SYS_TSTCLK_PCLK2 = 11,
	E_SYS_TSTCLK_GPIO = 12,
	E_SYS_TSTCLK_EBI = 13,
	E_SYS_TSTCLK_SRAM = 14,
	E_SYS_TSTCLK_PCLK_I2C0 = 16,
	E_SYS_TSTCLK_PCLK_PWM0 = 17,
	E_SYS_TSTCLK_PCLK_TMR0 = 18,
	E_SYS_TSTCLK_PCLK_TMR1 = 19,
	E_SYS_TSTCLK_PCLK_UART0 = 20,
	E_SYS_TSTCLK_PCLK_SPI0 = 21,
	E_SYS_TSTCLK_PCLK_RTC = 22,
	E_SYS_TSTCLK_PCLK_WDT = 23,
	E_SYS_TSTCLK_PCLK_USB = 24,
	E_SYS_TSTCLK_PCLK_ADC = 25,
	E_SYS_TSTCLK_PCLK_DAC = 26,
	E_SYS_TSTCLK_PCLK_LCD = 27,
	E_SYS_TSTCLK_PCLK_TK = 28,
	E_SYS_TSTCLK_PCLK_SPI2 = 29,
	E_SYS_TSTCLK_TMR0 = 32,
	E_SYS_TSTCLK_TMR1 = 33,
	E_SYS_TSTCLK_UART0 = 34,
	E_SYS_TSTCLK_USB = 35,
	E_SYS_TSTCLK_ADC = 36,
	E_SYS_TSTCLK_WDT = 37,
	E_SYS_TSTCLK_PWM0_CH01 = 38,
	E_SYS_TSTCLK_PWM0_CH23 = 39,
	E_SYS_TSTCLK_LCD = 41,
	E_SYS_TSTCLK_TK = 42,
	E_SYS_TSTCLK_PCLK_I2C1 = 48,
	E_SYS_TSTCLK_PCLK_PWM1 = 49,
	E_SYS_TSTCLK_PCLK_TMR2 = 50,
	E_SYS_TSTCLK_PCLK_TMR3 = 51,
	E_SYS_TSTCLK_PCLK_UART1 = 52,
	E_SYS_TSTCLK_PCLK_SPI1 = 53,
	E_SYS_TSTCLK_PCLK_I2S = 54,
	E_SYS_TSTCLK_PCLK_SC0 = 55,
	E_SYS_TSTCLK_TMR2 = 56,
	E_SYS_TSTCLK_TMR3 = 57,
	E_SYS_TSTCLK_UART1 = 58,
	E_SYS_TSTCLK_PWM1_CH01 = 59,
	E_SYS_TSTCLK_PWM1_CH23 = 60,
	E_SYS_TSTCLK_I2S = 61,
	E_SYS_TSTCLK_SC0 = 62,
	E_SYS_TSTCLK_SC1 = 63

}E_SYS_TSTCLK_SRC;


/*---------------------------------------------------------------------------------------------------------*/
/*  SYS Chip Clock Source		     				                                                       */
/*---------------------------------------------------------------------------------------------------------*/
typedef enum 
{
	E_SYS_HXT = 0x01,	/* HXT */
	E_SYS_LXT = 0x02,	/* LXT */
	E_SYS_HIRC = 0x04,	/* HIRC */
	E_SYS_LIRC = 0x08,	/* LIRC */
	E_SYS_PLL = 0x10      /* PLL */
}E_SYS_CHIP_CLKSRC;


/*---------------------------------------------------------------------------------------------------------*/
/*  PLL Clock In Freq.		     				                                          		               */
/*---------------------------------------------------------------------------------------------------------*/
typedef enum 
{
	E_SYS_PLLIN_4M, 
	E_SYS_PLLIN_8M, 
	E_SYS_PLLIN_12M, 
	E_SYS_PLLIN_15M, 
	E_SYS_PLLIN_24M
} E_SYS_PLLIN_CLK;


/*---------------------------------------------------------------------------------------------------------*/
/*  PLL Clock Out Freq.		     				                                          		               */
/*---------------------------------------------------------------------------------------------------------*/
typedef enum 
{
	E_SYS_PLLOUT_45M, 
	E_SYS_PLLOUT_48M, 
	E_SYS_PLLOUT_90M, 
	E_SYS_PLLOUT_96M, 
	E_SYS_PLLOUT_120M,
	E_SYS_PLLOUT_128M,
} E_SYS_PLLOUT_CLK;


/*--------------------------------------------------------------------------------------------------------*/
/*  Define IRC data structure                                                                             */
/*--------------------------------------------------------------------------------------------------------*/
typedef enum 
{
	E_SYS_TRIM_110592M=1,
	E_SYS_TRIM_12M=2,
	E_SYS_TRIM_12288M=3
} E_SYS_IRC_CLKSEL;


/* 
 * IP Clock Source Selection
 */
	/* HCLK Clock Source */
#define E_SYS_SEL0_HCLK_HXT	    (0x00)
#define E_SYS_SEL0_HCLK_LXT	    (0x01)
#define E_SYS_SEL0_HCLK_PLL	    (0x02)
#define E_SYS_SEL0_HCLK_LIRC	(0x03)
#define E_SYS_SEL0_HCLK_HIRC	(0x07)
	/* PLL Clock Source */
#define E_SYS_SEL0_PLL_HXT		(0x00)
#define E_SYS_SEL0_PLL_HIRC	    (0x01)
	/* UART Clock Source */
#define E_SYS_SEL1_UART_HXT	    (0x00)
#define E_SYS_SEL1_UART_LXT	    (0x01)
#define E_SYS_SEL1_UART_PLL	    (0x02)
#define E_SYS_SEL1_UART_HIRC	(0x03)
	/* ADC Clock Source */
#define E_SYS_SEL1_ADC_HXT 	    (0x00 << 2)
#define E_SYS_SEL1_ADC_LXT		(0x01 << 2)
#define E_SYS_SEL1_ADC_PLL		(0x02 << 2)
#define E_SYS_SEL1_ADC_HIRC	    (0x03 << 3)
	/* PWM0_CH01 Clock Source */
#define E_SYS_SEL1_PWM0_CH01_HXT	(0x00 << 4)
#define E_SYS_SEL1_PWM0_CH01_LXT	(0x01 << 4)
#define E_SYS_SEL1_PWM0_CH01_HCLK	(0x02 << 4)
#define E_SYS_SEL1_PWM0_CH01_HIRC	(0x03 << 4)
	/* PWM0_CH23 Clock Source */
#define E_SYS_SEL1_PWM0_CH23_HXT	(0x00 << 6)
#define E_SYS_SEL1_PWM0_CH23_LXT	(0x01 << 6)
#define E_SYS_SEL1_PWM0_CH23_HCLK	(0x02 << 6)
#define E_SYS_SEL1_PWM0_CH23_HIRC	(0x03 << 6)
	/* TMR0 Clock Source */
#define E_SYS_SEL1_TMR0_HXT	    (0x00 << 8)
#define E_SYS_SEL1_TMR0_LXT	    (0x01 << 8)
#define E_SYS_SEL1_TMR0_LIRC	(0x02 << 8)
#define E_SYS_SEL1_TMR0_EXT	    (0x03 << 8)
#define E_SYS_SEL1_TMR0_HIRC	(0x07 << 8)
	/* TMR1 Clock Source */
#define E_SYS_SEL1_TMR1_HXT	    (0x00 << 12)
#define E_SYS_SEL1_TMR1_LXT	    (0x01 << 12)
#define E_SYS_SEL1_TMR1_LIRC	(0x02 << 12)
#define E_SYS_SEL1_TMR1_EXT	    (0x03 << 12)
#define E_SYS_SEL1_TMR1_HIRC	(0x07 << 12)
	/* Touch Key Clock Source */
#define E_SYS_SEL1_TK_HXT		(0x00 << 16)
#define E_SYS_SEL1_TK_PLL		(0x01 << 16)
#define E_SYS_SEL1_TK_HIRC		(0x02 << 16)
	/* LCD Clock Source */
#define E_SYS_SEL1_LCD_LXT		(0x00 << 18)
#define E_SYS_SEL1_LCD_LIRC	    (0x01 << 18)
	/* FRQDIV Clock Source */
#define E_SYS_SEL2_FRQDIV_HXT		(0x00 << 2)
#define E_SYS_SEL2_FRQDIV_LXT		(0x01 << 2)
#define E_SYS_SEL2_FRQDIV_HCLK		(0x02 << 2)
#define E_SYS_SEL2_FRQDIV_HIRC		(0x03 << 2)
	/* PWM1_CH01 Clock Source */
#define E_SYS_SEL2_PWM1_CH01_HXT	(0x00 << 4)
#define E_SYS_SEL2_PWM1_CH01_LXT	(0x01 << 4)
#define E_SYS_SEL2_PWM1_CH01_HCLK	(0x02 << 4)
#define E_SYS_SEL2_PWM1_CH01_HIRC	(0x03 << 4)
	/* PWM1_CH23 Clock Source */
#define E_SYS_SEL2_PWM1_CH23_HXT	(0x00 << 6)
#define E_SYS_SEL2_PWM1_CH23_LXT	(0x01 << 6)
#define E_SYS_SEL2_PWM1_CH23_HCLK	(0x02 << 6)
#define E_SYS_SEL2_PWM1_CH23_HIRC	(0x03 << 6)
	/* TMR2 Clock Source */
#define E_SYS_SEL2_TMR2_HXT	    (0x00 << 8)
#define E_SYS_SEL2_TMR2_LXT	    (0x01 << 8)
#define E_SYS_SEL2_TMR2_LIRC	(0x02 << 8)
#define E_SYS_SEL2_TMR2_EXT	    (0x03 << 8)
#define E_SYS_SEL2_TMR2_HIRC	(0x07 << 8)
	/* TMR3 Clock Source */
#define E_SYS_SEL2_TMR3_HXT	    (0x00 << 12)
#define E_SYS_SEL2_TMR3_LXT	    (0x01 << 12)
#define E_SYS_SEL2_TMR3_LIRC	(0x02 << 12)
#define E_SYS_SEL2_TMR3_EXT	    (0x03 << 12)
#define E_SYS_SEL2_TMR3_HIRC	(0x07 << 12)
	/* I2S Clock Source */
#define E_SYS_SEL2_I2S_HXT		(0x00 << 16)
#define E_SYS_SEL2_I2S_PLL		(0x01 << 16)
#define E_SYS_SEL2_I2S_HIRC	    (0x03 << 16)
	/* Smart Card Clock Source */
#define E_SYS_SEL2_SC_HXT		(0x00 << 18)
#define E_SYS_SEL2_SC_PLL		(0x01 << 18)
#define E_SYS_SEL2_SC_HIRC		(0x03 << 18)


/*
 *  IP Clcok Enable
 */
/* APB Devices */
#define E_SYS_PEN_WDT	    (1 << 0)
#define E_SYS_PEN_RTC       (1 << 1)
#define E_SYS_PEN_TMR0	    (1 << 2)
#define E_SYS_PEN_TMR1      (1 << 3)
#define E_SYS_PEN_TMR2	    (1 << 4)
#define E_SYS_PEN_TMR3	    (1 << 5)
#define E_SYS_PEN_FDIV	    (1 << 6)
#define E_SYS_PEN_I2C0      (1 << 8)
#define E_SYS_PEN_I2C1	    (1 << 9)
#define E_SYS_PEN_SPI0	    (1 << 12)
#define E_SYS_PEN_SPI1	    (1 << 13)
#define E_SYS_PEN_SPI2	    (1 << 14)
#define E_SYS_PEN_UART0	    (1 << 16)
#define E_SYS_PEN_UART1	    (1 << 17)
#define E_SYS_PEN_PWM0_01	(1 << 20)
#define E_SYS_PEN_PWM0_23	(1 << 21)
#define E_SYS_PEN_PWM1_01	(1 << 22)
#define E_SYS_PEN_PWM1_23	(1 << 23)
#define E_SYS_PEN_TK		(1 << 24)
#define E_SYS_PEN_DAC	    (1 << 25)
#define E_SYS_PEN_LCD	    (1 << 26)
#define E_SYS_PEN_USBD	    (1 << 27)
#define E_SYS_PEN_ADC	    (1 << 28)
#define E_SYS_PEN_I2S	    (1 << 29)
#define E_SYS_PEN_SC0	    (1 << 30)
#define E_SYS_PEN_SC1	    (1 << 31)
/* AHB Devices */
#define E_SYS_HEN_GPIO	    (1 << 0)
#define E_SYS_HEN_PDMA	    (1 << 1)
#define E_SYS_HEN_ISP	    (1 << 2)
#define E_SYS_HEN_EBI	    (1 << 3)
#define E_SYS_HEN_SRAM	    (1 << 4)
#define E_SYS_HEN_TICK	    (1 << 5)

/*
 * Struture to store Peripheral devices clock divider
 */
typedef struct {
    uint8_t	 u8USBDiv; 	/* 0 ~ 15 */
    uint8_t	 u8UARTDiv; /* 0 ~ 15 */
    uint8_t	 u8I2SDiv; 	/* 0 ~ 15 */
    uint8_t	 u8ADCDiv; 	/* 0 ~ 255 */
    uint8_t	 u8TKDiv;	/* 0 ~ 15 */
    uint8_t	 u8SC0Div; 	/* 0 ~ 15 */	
    uint8_t	 u8SC1Div; 	/* 0 ~ 15 */
    uint8_t RESERVED0;	
}S_SYS_IP_CLKDIV;


/*
 * Struture to store HCLK (CPU) and PLL clock configurations
 */
typedef struct {
    uint8_t	 u8ClkEnable;	/* E_SYS_HXT | E_SYS_LXT | E_SYS_HIRC | E_SYS_LIRC | E_SYS_PLL */
    int8_t eHClkSrc; 		/* E_SYS_SEL0_HCLK_XXX */
    int8_t u8HClkDiv;		/* 0 ~ 15 */
    int8_t ePLLClkSrc;	     /* E_SYS_SEL0_PLL_HXT or E_SYS_SEL0_PLL_HIRC */
    int8_t ePLLInFreq;  /* E_SYS_PLLIN_CLK */
    int8_t ePLLOutFreq; /* E_SYS_PLLOUT_CLK */
    uint8_t RESERVED0[2];	
} S_SYS_CHIP_CLKCFG;


/*
 * Struture to store IP clock configurations
 */
typedef struct {
    uint32_t u32AHBClkEn;	/* E_SYS_HEN_GPIO |E_SYS_HEN_PDMA | E_SYS_HEN_ISP |E_SYS_HEN_EBI |E_SYS_HEN_SRAM | E_SYS_HEN_TICK */
    uint32_t u32APBClkEn; 	/* E_SYS_PEN_XXX |  E_SYS_PEN_XXX | .... E_SYS_PEN_XXX */
    uint32_t u32ClkSel1;
    uint32_t u32ClkSel2;
    S_SYS_IP_CLKDIV sClkDiv;		
} S_SYS_IP_CLKCFG;


typedef void (*BOD_CALLBACK)(void);
typedef void (*PWRWU_CALLBACK)(void);

/*---------------------------------------------------------------------------------------------------------*/
/* Define SYS functions prototype                                                                          */
/*---------------------------------------------------------------------------------------------------------*/
void 	 DrvSYS_ClearClockSwitchStatus(void);
uint32_t DrvSYS_ClearResetSource(uint32_t u32Src);

void 	 DrvSYS_Delay(uint32_t us);
void 	 DrvSYS_DisablePOR(void);

void 	 DrvSYS_EnablePOR(void);
void 	 DrvSYS_EnterPowerDown(void);

uint32_t DrvSYS_GetBODState(void);
int32_t  DrvSYS_GetChipClockSourceStatus(E_SYS_CHIP_CLKSRC eClkSrc);
uint32_t DrvSYS_GetClockSwitchStatus(void);
uint32_t DrvSYS_GetExtClockFreq(void);
uint32_t DrvSYS_GetHCLKFreq(void);
uint32_t DrvSYS_GetPLLClockFreq(void);
uint32_t DrvSYS_GetPLLContent(E_SYS_PLL_CLKSRC ePllSrc, uint32_t u32PllClk);
uint32_t DrvSYS_GetResetSource(void);
uint32_t DrvSYS_GetVersion(void);

int32_t  DrvSYS_IsProtectedRegLocked(void);

int32_t  DrvSYS_LockProtectedReg(void);

int32_t  DrvSYS_Open(uint32_t u32Hclk);
int32_t  DrvSYS_OpenExt(S_SYS_CHIP_CLKCFG *sChipCfg, S_SYS_IP_CLKCFG *sIPCfg);

uint32_t DrvSYS_ReadProductID(void);
void 	 DrvSYS_ResetChip(void);
void 	 DrvSYS_ResetCPU(void);
void 	 DrvSYS_ResetIP(E_SYS_IP_RST eIpRst);

void 	 DrvSYS_SelectBODVolt(uint8_t u8Volt);
int32_t  DrvSYS_SelectHCLKSource(uint8_t u8ClkSrcSel);
int32_t  DrvSYS_SelectIPClockSource(uint32_t u32IpClkSrc, uint8_t u8ClkSrcSel);
void 	 DrvSYS_SelectPLLSource(E_SYS_PLL_CLKSRC ePllSrc);
void     DrvSYS_SetBODFunction(int32_t i32Enalbe, int32_t i32Mode, BOD_CALLBACK bodcallbackFn, int32_t i32Volt);
int32_t  DrvSYS_SetClockDivider(uint32_t u32IpDiv , int32_t i32value);
int32_t  DrvSYS_SetFreqDividerOutput(int32_t i32Flag, uint8_t u8Divider);
void 	 DrvSYS_SetIPClock(E_SYS_IP_CLK eIpClk, int32_t i32Enable);
int32_t  DrvSYS_SetOscCtrl(E_SYS_CHIP_CLKSRC eClkSrc, int32_t i32Enable);
void     DrvSYS_SetPLLContent(uint32_t u32PllContent);
void 	 DrvSYS_SetPLLMode(int32_t i32Flag);
void     DrvSYS_SetPowerDownWakeUpInt(int32_t i32Enable, PWRWU_CALLBACK pdwucallbackFn, int32_t i32enWUDelay);

int32_t  DrvSYS_UnlockProtectedReg(void);

int32_t  DrvSYS_EnableAutoTrim(E_SYS_IRC_CLKSEL eTrimClk, DRVSYS_IRC_CALLBACK pfncallback);
void     DrvSYS_DisableAutoTrim(void);

#endif

